import { useEffect, useRef, useState, useMemo } from 'react';
import Taro, { useRouter } from '@tarojs/taro';
import { useRequest } from 'ahooks';

import {
    SeatAuto,
    SeatWarningToast,
    SeatWarningToastRefType,
    SeatRender,
    Tickets,
} from './components';

import styles from './index.module.less';
import { useMovieStore } from '@/common/hox/movieStore';
import { isLeaveNextSeatsEmpty, getMovieCinemaScheduleSeat } from '@/service';
import { usePageShow } from '@/common/hook/usePage';
import { PageUrlMap } from '@/utils/enum';
import { PageUrlEnum } from '@/utils/enum';
import { MovableArea, MovableView } from '@tarojs/components';
import { getSeatPrice } from '@/common/utils';
import { useTicketModeStore } from '@/common/hox/ticketModeStore';
import { useInitStore } from '@/common/hox/initStore';
import appConfig from '@/utils/appConfig';
const colorList = [
    '#2bb4ff',
    'var(--color-main)',
    '#2e70ff',
    '#ff8c43',
    '#fec03d',
    '#66c130',
    '#9bd95d',
];
import classNames from 'classnames';
import { CustomNavBar } from '@/components';

// router params
type RouterParamType = {
    movieId: string;
    isvId: string;
    showId: string;
    storeId: string;
};
type SeatSelectPagePropsType = {
    cinemaUrl?: string;
    confirmUrl?: string;
};
const seatSelectPage = (props: SeatSelectPagePropsType) => {
    const {
        cinemaUrl = PageUrlMap.get(PageUrlEnum.TheaterList),
        confirmUrl = PageUrlMap.get(PageUrlEnum.MovieOrderConfirm),
    } = props;
    const { params } = useRouter<RouterParamType>();
    const { movieId, isvId, showId, storeId } = params;
    const { initReady } = useInitStore();
    const {
        cinema: { cinemaInfo },
        movie: { movieDetail },
        schedule: { scheduleDetail, scheduleSeatInfo, setScheduleDetail, setScheduleSeatInfo },
        seat: { seatList, seatTotalPrice },
        coupon: { hasCoupon },
        combination: { combinationInfo },
    } = useMovieStore((store) => [
        store.cinema.cinemaInfo,
        store.movie.movieDetail,
        store.coupon.hasCoupon,
        store.schedule.scheduleDetail,
        store.schedule.scheduleSeatInfo,
        store.schedule.setScheduleDetail,
        store.schedule.setScheduleSeatInfo,
        store.seat.seatList,
        store.seat.seatTotalPrice,
        store.combination.combinationInfo,
    ]);

    usePageShow(() => {
        if ((cinemaUrl && !movieDetail) || !scheduleDetail)
            Taro.redirectTo({
                url: `${cinemaUrl}?movieId=${movieId}&cinemaId=${storeId}`,
            });
    });

    useEffect(() => {
        if (cinemaInfo?.cinemaName) {
            if (process.env.TARO_ENV === 'h5') {
                document.title = cinemaInfo.cinemaName;
            } else {
                Taro.setNavigationBarTitle({ title: cinemaInfo.cinemaName });
            }
        }
    }, [cinemaInfo?.cinemaName]);

    // 座位价格
    const { totalSellPrice, totalOfficialPrice, totalReducePrice } = seatTotalPrice;

    // 校验座位跳转
    const seatWarningToastRef = useRef<SeatWarningToastRefType>(null);

    // 锁定座位
    const isLeaveNextSeatsEmptyApi = useRequest(
        async () => {
            Taro.showToast({
                title: '锁座中，正在为您计算最大优惠',
                icon: 'none',
                // image: 'https://fulu-media.oss-cn-hangzhou.aliyuncs.com/public/icon/loadin-l.gif',
                duration: 2000,
            });
            if (scheduleDetail) {
                const scheduleItem = { ...scheduleDetail };
                scheduleItem.originPrice = seatList[0]?.officialPrice || scheduleDetail.originPrice;
                setScheduleDetail(scheduleItem);
            }
            if (!movieDetail || !cinemaInfo) {
                Taro.showToast({
                    title: '影院或影片信息不存在',
                    icon: 'error',
                    duration: 2000,
                });
                return;
            }

            const res = await isLeaveNextSeatsEmpty({
                filmId: movieDetail.movieCode,
                storeId: cinemaInfo.cinemaId ? cinemaInfo.cinemaId : cinemaInfo.cinemaCode,
                showId: showId,
                seatItems: seatList.map((seat) => ({
                    columnNo: seat.columnNo,
                    rowNo: seat.rowNo,
                    seatName: seat.seatNo,
                })),
            });
            return res;
        },
        {
            manual: true,
            onSuccess: (res) => {
                Taro.hideToast();
                if (res === undefined) return;
                if (res.isEmpty) {
                    confirmUrl && Taro.navigateTo({ url: `${confirmUrl}?movieId=${movieId}` });
                    return;
                }
                if (!res.isEmpty) {
                    seatWarningToastRef.current?.show();
                    return;
                }
            },
        }
    );

    // 获取场次座位信息
    const getMovieCinemaScheduleSeatApi = useRequest(
        async (params) => {
            const res = await getMovieCinemaScheduleSeat(params);
            if (res?.isvFilmSeatData.length < 1) {
                Taro.showModal({
                    title: '提示',
                    content: '当前场次暂无座位可选，请更换再试',
                    showCancel: false,
                    success: function (res) {
                        if (res.confirm) {
                            Taro.navigateBack();
                        } else if (res.cancel) {
                        }
                    },
                });
                return false;
            }
            if (appConfig.movieConfig?.priceFormatter) {
                const formatter = appConfig.movieConfig.priceFormatter;
                res.isvFilmSeatAreaPriceData = res.isvFilmSeatAreaPriceData.map((item) => {
                    item.fastPrice = formatter(item.fastPrice);
                    item.specialPrice = formatter(item.specialPrice);
                    return item;
                });
                res.isvFilmSeatData = res.isvFilmSeatData.map((item) => {
                    item.fastPrice = formatter(item.fastPrice);
                    item.specialPrice = formatter(item.specialPrice);
                    return item;
                });
            }
            return res;
        },
        {
            ready: Boolean(
                initReady && movieDetail && scheduleDetail && movieId && showId && storeId
            ),
            defaultParams: [
                {
                    filmId: movieId,
                    isvId,
                    showId,
                    storeId,
                },
            ],
            onBefore: () => Taro.showLoading({
                title:'加载中'
            }),
            onSuccess: (res) => {
                if (!res) return;
                const { isvFilmSeatData, isvFilmSeatAreaPriceData, ...scheduleSeatInfo } = res;
                setScheduleSeatInfo(scheduleSeatInfo);
            },
            onFinally: () => Taro.hideLoading(),
        }
    );

    const data = useMemo(() => {
        return getMovieCinemaScheduleSeatApi.data &&
            'isvFilmSeatData' in getMovieCinemaScheduleSeatApi.data
            ? getMovieCinemaScheduleSeatApi.data.isvFilmSeatData
            : [];
    }, [getMovieCinemaScheduleSeatApi.data]);

    const { ticketModeList } = useTicketModeStore();

    const seatType = useMemo(() => {
        const res = (
            getMovieCinemaScheduleSeatApi.data &&
            'isvFilmSeatAreaPriceData' in getMovieCinemaScheduleSeatApi.data
                ? getMovieCinemaScheduleSeatApi.data.isvFilmSeatAreaPriceData
                : []
        )
            .map((item) =>
                getSeatPrice(item, scheduleDetail?.originPrice == scheduleDetail?.salePrice)
            )
            .sort((a, b) => a.sellPrice - b.sellPrice)
            .map((item, index) => {
                while (index >= colorList.length) index -= colorList.length;
                return {
                    ...item,
                    seatTypeColor: colorList[index],
                };
            });
        return res;
    }, [getMovieCinemaScheduleSeatApi.data, hasCoupon, ticketModeList]);

    const seatData = useMemo(() => {
        const res: (Movie.IsvFilmSeatDatum | null)[][] = [];
        const minRow = Math.min(...data.map((item) => Number(item.rowNo)));
        data.forEach((item) => {
            const { rowNo } = item;
            const rowIndex = parseInt(rowNo) - minRow;
            res[rowIndex] ??= [];
            res[rowIndex].push(item);
        });
        return res;
    }, [data]);

    const [scale, setScale] = useState(1.2);
    const positionRef = useRef({ x: 0, y: 0 });
    const handleScaleChange = (e) => {
        setScale(e.detail.scale > 1 ? 1.2 : 1);
    };
    const [scaleLeft, setScaleLeft] = useState(10);
    const handleChange = (e) => {
        setScaleLeft(e.detail.x < -10 ? (-e.detail.x > 22 ? -e.detail.x + 10 : 12) : 12);
    };
    const [seatMaxX, setSeatMaxX] = useState(0);
    useEffect(() => {
        let maxX = Math.max(...seatData.map((item) => item?.length));

        setSeatMaxX(maxX);
    }, [seatData]);
    const { screenHeight, statusBarHeight, screenWidth } = Taro.getSystemInfoSync();
    const seatHeight =
        (screenHeight -
            (statusBarHeight !== undefined && !Number.isNaN(statusBarHeight)
                ? statusBarHeight
                : 0) -
            (550 * screenWidth) / 750) *
        0.95;

    return (
        <div className={styles.page}>
            <CustomNavBar title={movieDetail?.name || cinemaInfo?.cinemaName || '电影选座'} />
            {/* 票价 */}
            <div className={styles.header}>
                <div className={styles.seatType}>
                    {seatType.map((item, index) => {
                        const { sellPrice, lineThroughPrice, seatTypeColor, sectionId } = item;
                        if (sellPrice === undefined || !sellPrice || !sectionId) return;
                        return (
                            <div
                                key={index}
                                className={styles.priceItem}
                                style={
                                    {
                                        '--seatTypeColor': seatTypeColor as string,
                                    } as React.CSSProperties
                                }
                            >
                                <div className={styles.icon}></div>
                                <span className={styles.price}> ¥{sellPrice}</span>
                                {lineThroughPrice && (
                                    <span className={styles.lineThrough}>¥{lineThroughPrice}</span>
                                )}
                            </div>
                        );
                    })}
                </div>
            </div>
            {/* 座位图 */}
            <div className={styles.movableArea}>
                <MovableArea
                    style={{
                        width: `100%`,
                        height: `${seatHeight}px`,
                        overflow: 'hidden',
                        maxHeight: screenHeight * 0.6,
                    }}
                >
                    <MovableView
                        className={styles.movableView}
                        direction="all"
                        style={{
                            width: `750px`,
                            height: `${seatHeight * 0.7}px`,
                            minWidth: '375px',
                        }}
                        scaleMin={0.8}
                        scaleMax={1.2}
                        x={-((20 * seatMaxX) / 3) - seatMaxX / scale}
                        y={positionRef.current.y}
                        scale
                        outOfBounds={true}
                        scaleValue={scale}
                        onScale={handleScaleChange}
                        animation={true}
                        onChange={handleChange}
                        // onTouchStart={handleButtonClick}
                    >
                        <SeatRender
                            scaleLeft={scaleLeft}
                            scale={scale}
                            seatData={seatData}
                            seatType={seatType}
                            headerExtra={
                                <div className={styles.hallName}>{scheduleDetail?.hallName}</div>
                            }
                        />
                    </MovableView>
                </MovableArea>
                {
                    <div className={styles.seatTypeGuid}>
                        {['已售', '未售', '情侣座', '已选'].map((item, index) => {
                            let statusClass = '';
                            if (index === 0) statusClass = styles.soldOut;
                            if (index === 1) statusClass = styles.validSeat;
                            if (index === 2) statusClass = styles.loveSeat;
                            if (index === 3) statusClass = styles.selected;

                            return (
                                <div
                                    key={item}
                                    className={classNames(styles.seatTypeItem, statusClass)}
                                >
                                    <div className={styles.icon}></div>
                                    {index === 2 && (
                                        <div
                                            className={classNames(styles.icon, styles.iconRight)}
                                        ></div>
                                    )}
                                    <span className={styles.text}> {item}</span>
                                </div>
                            );
                        })}
                    </div>
                }
            </div>
            <Tickets />
            <SeatAuto />
            <div
                className={styles.button}
                onClick={() => {
                    if (!seatList.length)
                        return Taro.showToast({ title: '请选择座位', icon: 'error' });
                    !isLeaveNextSeatsEmptyApi.loading && isLeaveNextSeatsEmptyApi.run();
                }}
            >
                {!seatList.length ? (
                    <div className={styles.buttonTextLarge}>请选座位</div>
                ) : combinationInfo ? (
                    <>
                        <div className={styles.buttonTextMiddle}>{totalSellPrice}元 确认选座</div>
                        <div className={styles.buttonTextSmall}>权益卡包支付</div>
                    </>
                ) : hasCoupon ? (
                    <div className={styles.buttonTextLarge}>{totalSellPrice}元 确认选座</div>
                ) : (
                    <>
                        <div className={styles.buttonTextMiddle}>
                            {scheduleSeatInfo?.hasCoupon ? totalOfficialPrice : totalSellPrice}元
                            确认选座
                        </div>
                        <div className={styles.buttonTextSmall}>
                            市场价：￥{totalOfficialPrice} 省：￥
                            {scheduleSeatInfo?.hasCoupon ? 0 : totalReducePrice}
                        </div>
                    </>
                )}
            </div>
            <SeatWarningToast ref={seatWarningToastRef} />
        </div>
    );
};
export default seatSelectPage;
